package com.hksj.cbm.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hksj.cbm.dto.DeviceRoomTrusteeshipConfigDTO;
import com.hksj.cbm.dto.DeviceRoomTrusteeshipConfigQueryDTO;
import com.hksj.cbm.entity.DeviceRoomTrusteeshipConfig;
import com.hksj.cbm.mapper.DeviceRoomTrusteeshipConfigMapper;
import com.hksj.cbm.vo.DeviceRoomTrusteeshipConfigVO;
import com.hksj.common.core.common.Constants;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author fjt
 * @data 2024/8/17 15:36
 * @describe 设备托管房间
 */
@Service
public class DeviceRoomTrusteeshipConfigService extends ServiceImpl<DeviceRoomTrusteeshipConfigMapper, DeviceRoomTrusteeshipConfig> {



    /**
     * 查询指定楼层中、指定设备已设置和可设置的房间信息
     * @param dto
     * @return
     */
    public List<DeviceRoomTrusteeshipConfigVO>  queryConfig(DeviceRoomTrusteeshipConfigQueryDTO dto){
        // 查询指定楼层内全部可用的房间和当前设备已经设置的房间(即：指定楼层内的房间中，去掉其他设备已经设置的房间)
        List<DeviceRoomTrusteeshipConfigVO> list = baseMapper.queryRoomByDeviceId(dto);
        if (CollUtil.isEmpty(list)){
            return null;
        }

        // 查询指定设备已经设置的房间信息
        LambdaQueryWrapper<DeviceRoomTrusteeshipConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceRoomTrusteeshipConfig::getDeviceId, dto.getDeviceId());
        List<DeviceRoomTrusteeshipConfig> configList = baseMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(configList)){
            return list;
        }
        List<Long> selectedRoomList = configList.stream().map(DeviceRoomTrusteeshipConfig::getRoomId).collect(Collectors.toList());

        //  把list中当前设备已经设置的房间标记为已设置
        list.forEach(configVO -> {
            if (selectedRoomList.contains(configVO.getRoomId())){
                configVO.setIsSelected(Constants.ONE);
            }
        });
        return list;
    }


    /**
     * 批量更新设备托管房间配置信息(一次更新同一个设备在多个房间的配置信息)
     * @param dto
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public String batchReplaceConfig(DeviceRoomTrusteeshipConfigDTO dto){
        // 查出当前楼层内都有哪些房间
        List<Long> allRoomIdList = baseMapper.queryRoomByPaths(dto.getPaths());
        if (CollUtil.isEmpty(allRoomIdList)){
            throw new RuntimeException("数据异常，当前路径下没有查到房间信息");
        }
        // 判断房间是否重复配置
        if (CollUtil.isNotEmpty(dto.getRoomIdList())){
            LambdaQueryWrapper<DeviceRoomTrusteeshipConfig> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(DeviceRoomTrusteeshipConfig::getRoomId, dto.getRoomIdList());
            queryWrapper.ne(DeviceRoomTrusteeshipConfig::getDeviceId, dto.getDeviceId());
            int count = baseMapper.selectCount(queryWrapper);
            if (count > 0){
                throw new RuntimeException("数据异常，所选的房间中存在已被其他设备关联的情况，同一个房间只能配置给一个设备");
            }
        }

        // 查询设备在当前楼层内已有的房间配置信息
        List<DeviceRoomTrusteeshipConfig> list = baseMapper.queryConfigByDeviceId(allRoomIdList, dto.getDeviceId());
        if (CollUtil.isEmpty(list)){
            // 没有设置过，直接新增
            List<DeviceRoomTrusteeshipConfig> configList = buildDeviceRoomTrusteeshipConfig(dto);
            Boolean bool = saveBatch(configList);
            if (!bool){
                throw new RuntimeException("更新设备的托管房间配置信息失败");
            }
        }else {
            // 删除设备在当前楼层内原有的托管房间配置信息
            List<Long> configIdList = list.stream().map(DeviceRoomTrusteeshipConfig::getId).collect(Collectors.toList());
            int num = baseMapper.deleteBatchIds(configIdList);
            if (num <= 0){
                throw new RuntimeException("删除当前设备原有的托管房间配置信息失败");
            }
            if (CollUtil.isNotEmpty(dto.getRoomIdList())){
                // 把当前更新的配置信息新增到配置表中
                List<DeviceRoomTrusteeshipConfig> configList = buildDeviceRoomTrusteeshipConfig(dto);
                Boolean bool = saveBatch(configList);
                if (!bool){
                    throw new RuntimeException("更新设备的托管房间配置信息失败");
                }
            }
        }
        return "更新设备的托管房间配置信息成功";
    }


    private List<DeviceRoomTrusteeshipConfig> buildDeviceRoomTrusteeshipConfig(DeviceRoomTrusteeshipConfigDTO dto){
        List<Long> roomIdList = dto.getRoomIdList();
        Assert.notEmpty(roomIdList, "更新设备的托管房间配置信息失败，房间id集合不能为空");
        List<DeviceRoomTrusteeshipConfig> list = new ArrayList<>();
        roomIdList.forEach(roomId -> {
            DeviceRoomTrusteeshipConfig config = new DeviceRoomTrusteeshipConfig();
            config.setProductId(dto.getProductId());
            config.setDeviceId(dto.getDeviceId());
            config.setRoomId(roomId);
            list.add(config);
        });
        return list;
    }

}
